home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / rsynth / src / saynum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  5.4 KB  |  222 lines

  1.  
  2. #include <stdio.h>
  3. #include "proto.h"
  4. #include "darray.h"
  5. #include "say.h"
  6.  
  7. /*
  8. **              Integer to Readable ASCII Conversion Routine.
  9. **
  10. ** Synopsis:
  11. **
  12. **      say_cardinal(value)
  13. **              long int     value;          -- The number to output
  14. **
  15. **      The number is translated into a string of words
  16. **
  17. */
  18. static char *Cardinals[] =
  19. {
  20.  "zero", "one", "two", "three",
  21.  "four", "five", "six", "seven",
  22.  "eight", "nine",
  23.  "ten", "eleven", "twelve", "thirteen",
  24.  "fourteen", "fifteen", "sixteen", "seventeen",
  25.  "eighteen", "nineteen"
  26. };
  27.  
  28.  
  29. static char *Twenties[] =
  30. {
  31.  "twenty", "thirty", "forty", "fifty",
  32.  "sixty", "seventy", "eighty", "ninety"
  33. };
  34.  
  35.  
  36. static char *Ordinals[] =
  37. {
  38.  "zeroth", "first", "second", "third",
  39.  "fourth", "fifth", "sixth", "seventh",
  40.  "eighth", "ninth",
  41.  "tenth", "eleventh", "twelfth", "thirteenth",
  42.  "fourteenth", "fifteenth", "sixteenth", "seventeenth",
  43.  "eighteenth", "nineteenth"
  44. };
  45.  
  46.  
  47. static char *Ord_twenties[] =
  48. {
  49.  "twentieth", "thirtieth", "fortieth", "fiftieth",
  50.  "sixtieth", "seventieth", "eightieth", "ninetieth"
  51. };
  52.  
  53. /*
  54. ** Translate a number to phonemes.  This version is for CARDINAL numbers.
  55. **       Note: this is recursive.
  56. */
  57. unsigned
  58. xlate_cardinal(value, phone)
  59. long int value;
  60. darray_ptr phone;
  61. {
  62.  unsigned nph = 0;
  63.  if (value < 0)
  64.   {
  65.    nph += xlate_string("minus", phone);
  66.    value = (-value);
  67.    if (value < 0) /* Overflow!  -32768 */
  68.     {
  69.      nph += xlate_string("a lot", phone);
  70.      return nph;
  71.     }
  72.   }
  73.  if (value >= 1000000000L)
  74.   /* Billions */
  75.   {
  76.    nph += xlate_cardinal(value / 1000000000L, phone);
  77.    nph += xlate_string("billion", phone);
  78.    value = value % 1000000000;
  79.    if (value == 0)
  80.     return nph;      /* Even billion */
  81.    if (value < 100)
  82.     nph += xlate_string("and", phone);
  83.                                        /* as in THREE BILLION AND FIVE */
  84.   }
  85.  if (value >= 1000000L)
  86.                                 /* Millions */
  87.   {
  88.    nph += xlate_cardinal(value / 1000000L, phone);
  89.    nph += xlate_string("million", phone);
  90.    value = value % 1000000L;
  91.    if (value == 0)
  92.     return nph;      /* Even million */
  93.    if (value < 100)
  94.     nph += xlate_string("and", phone);
  95.                                        /* as in THREE MILLION AND FIVE */
  96.   }
  97.  
  98.  /* Thousands 1000..1099 2000..99999 */
  99.  /* 1100 to 1999 is eleven-hunderd to ninteen-hunderd */
  100.  if ((value >= 1000L && value <= 1099L) || value >= 2000L)
  101.   {
  102.    nph += xlate_cardinal(value / 1000L, phone);
  103.    nph += xlate_string("thousand", phone);
  104.    value = value % 1000L;
  105.    if (value == 0)
  106.     return nph;      /* Even thousand */
  107.    if (value < 100)
  108.     nph += xlate_string("and", phone);
  109.                                        /* as in THREE THOUSAND AND FIVE */
  110.   }
  111.  if (value >= 100L)
  112.   {
  113.    nph += xlate_string(Cardinals[value / 100], phone);
  114.    nph += xlate_string("hundred", phone);
  115.    value = value % 100;
  116.    if (value == 0)
  117.     return nph;      /* Even hundred */
  118.   }
  119.  if (value >= 20)
  120.   {
  121.    nph += xlate_string(Twenties[(value - 20) / 10], phone);
  122.    value = value % 10;
  123.    if (value == 0)
  124.     return nph;      /* Even ten */
  125.   }
  126.  nph += xlate_string(Cardinals[value], phone);
  127.  return nph;
  128. }
  129.  
  130. /*
  131. ** Translate a number to phonemes.  This version is for ORDINAL numbers.
  132. **       Note: this is recursive.
  133. */
  134. unsigned
  135. xlate_ordinal(value, phone)
  136. long int value;
  137. darray_ptr phone;
  138. {
  139.  unsigned nph = 0;
  140.  if (value < 0)
  141.   {
  142.    nph += xlate_string("minus", phone);
  143.    value = (-value);
  144.    if (value < 0) /* Overflow!  -32768 */
  145.     {
  146.      nph += xlate_string("a lot", phone);
  147.      return nph;
  148.     }
  149.   }
  150.  if (value >= 1000000000L)
  151.   /* Billions */
  152.   {
  153.    nph += xlate_cardinal(value / 1000000000L, phone);
  154.    value = value % 1000000000;
  155.    if (value == 0)
  156.     {
  157.      nph += xlate_string("billionth", phone);
  158.      return nph;     /* Even billion */
  159.     }
  160.    nph += xlate_string("billion", phone);
  161.    if (value < 100)
  162.     nph += xlate_string("and", phone);
  163.                                        /* as in THREE BILLION AND FIVE */
  164.   }
  165.  
  166.  if (value >= 1000000L)
  167.                                 /* Millions */
  168.   {
  169.    nph += xlate_cardinal(value / 1000000L, phone);
  170.    value = value % 1000000L;
  171.    if (value == 0)
  172.     {
  173.      nph += xlate_string("millionth", phone);
  174.      return nph;     /* Even million */
  175.     }
  176.    nph += xlate_string("million", phone);
  177.    if (value < 100)
  178.     nph += xlate_string("and", phone);
  179.                                        /* as in THREE MILLION AND FIVE */
  180.   }
  181.  
  182.  /* Thousands 1000..1099 2000..99999 */
  183.  /* 1100 to 1999 is eleven-hunderd to ninteen-hunderd */
  184.  if ((value >= 1000L && value <= 1099L) || value >= 2000L)
  185.   {
  186.    nph += xlate_cardinal(value / 1000L, phone);
  187.    value = value % 1000L;
  188.    if (value == 0)
  189.     {
  190.      nph += xlate_string("thousandth", phone);
  191.      return nph;     /* Even thousand */
  192.     }
  193.    nph += xlate_string("thousand", phone);
  194.    if (value < 100)
  195.     nph += xlate_string("and", phone);
  196.                                        /* as in THREE THOUSAND AND FIVE */
  197.   }
  198.  if (value >= 100L)
  199.   {
  200.    nph += xlate_string(Cardinals[value / 100], phone);
  201.    value = value % 100;
  202.    if (value == 0)
  203.     {
  204.      nph += xlate_string("hundredth", phone);
  205.      return nph;     /* Even hundred */
  206.     }
  207.    nph += xlate_string("hundred", phone);
  208.   }
  209.  if (value >= 20)
  210.   {
  211.    if ((value % 10) == 0)
  212.     {
  213.      nph += xlate_string(Ord_twenties[(value - 20) / 10], phone);
  214.      return nph;     /* Even ten */
  215.     }
  216.    nph += xlate_string(Twenties[(value - 20) / 10], phone);
  217.    value = value % 10;
  218.   }
  219.  nph += xlate_string(Ordinals[value], phone);
  220.  return nph;
  221. }
  222.